package study.itwill.team5.board;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;

import org.apache.log4j.Logger;

import study.itwill.common.DBHandler;
import study.itwill.common.DateTime;

/**
 * 게시판 카테고리 - 추가, 수정, 삭제, 조회, 리스트 기능을 가진 클래스
 */
public class BoardCategory {
	// Logger 클래스의 인스턴스를 받아온다.
	static Logger logger = Logger.getLogger(BoardCategory.class);
		
	private static final String TABLE = "board_category";
	
	// 데이터베이스 제어 객체에 대한 참조
	DBHandler db = null;
	
	/** 현재시간 데이터 저장을 위한 SQL구문 작성 */
	String datetime = DateTime.getInstance().getNowDateTimeString();
	
	public BoardCategory() {
		// DB객체에 대한 참조 연결
		db = DBHandler.getInstance();
	}
	
	
	/**
	 * 게시판 카테고리 추가를 위한 기능
	 * @param category_name		- 게시판 카테고리 이름
	 * @return int				- 추가된 게시판 카테고리에 대한 일련번호를 리턴
	 */
	public int addBoardCategory(String category_name) {
		//-----------------------------------------
		// 메서드 시작
		//-----------------------------------------
		logger.debug("=============== method start >> addBoardCategory");
		logger.debug("[PARAMS] category_name=" + category_name);
		
		int seq = -1;
		
		// SQL 인젝션 방어
		category_name = category_name.replace("'", "\'");
		
		// 트랜젝션에 대한 판단이 잘 서지 않는다면, 무조건 하면 된다.
		db.beginTrans();
		
		// INSERT 처리를 위한 구현
		String sql = "INSERT INTO board_category("
	            + "category_name, reg_date, edit_date"
	            + ") VALUES ('%s', '%s', '%s');";
		
		boolean result = db.execSql(sql, category_name, datetime, datetime);
		
		//-----------------------------------------
		// 결과처리
		//-----------------------------------------
		if(result) {
			db.commit();
			seq = db.getMax(TABLE, "seq", null);
			logger.debug("처리결과 >> " + seq + "번 게시판 카테고리 등록 성공");
		} else {
			db.rollback();
			logger.error("처리결과 >> 게시판 카테고리 추가 실패");
		}
		
		logger.debug("=============== method end >> addBoardCategory");
		
		return seq;
	}
	
	/**
	 * 게시판 카테고리 수정을 위한 기능
	 * @param seq				- 게시판 카테고리 일련번호
	 * @param category_name		- 게시판 카테고리 이름
	 * @return boolean			- true - 게시판 카테고리 수정 성공 / false - 게시판 카테고리 수정 실패
	 */
	public boolean editBoardCategory(int seq, String category_name) {
		logger.debug("=============== method start >> editBoardCategory");
		logger.debug("[PARAMS] seq=" + seq);
		logger.debug("[PARAMS] category_name=" + category_name);
		
		// SQL 인젝션 방어
		category_name = category_name.replace("'", "\'");
		
		boolean result = false;
		
		db.beginTrans();
		
		String sql = "UPDATE board_category "
				+ "SET category_name = '%s', edit_date = '%s' "
				+ "WHERE seq = %d;";
		
		result = db.execSql(sql, category_name, datetime, seq);
		
		if(result) {
			db.commit();
			logger.debug("처리결과 >> " + seq + "번 게시판 카테고리 수정성공");
		} else {
			db.rollback();
			logger.error("처리결과 >> 데이터 수정 실패 ");
		}
		
		logger.debug("=============== method end >> editBoardCategory");
		
		return result;
	}
	
	/**
	 * 게시판 카테고리 삭제를 위한 기능
	 * @param seq		- 게시판 카테고리 일련번호
	 * @return boolean	- true - 게시판 카테고리 삭제 성공 / false - 게시판 카테고리 삭제 실패
	 */
	public boolean deleteBoardCategory(int seq) {
		logger.debug("=============== method start >> deleteBoardCategory");
		logger.debug("[PARAMS] seq=" + seq);
		
		boolean result = false;
		
		// 이 데이터를 참조하는 다른 데이터들의 존재 여부 검사
		// SELECT COUNT(studno) FROM student WHERE profno=?
		if (db.getCount("board", "seq", "board_category_seq=" + seq) > 0) {
			logger.error("참조 무결성 위반");
			return result;
		}
		
		db.beginTrans();
		
		String sql = "DELETE FROM board_category WHERE seq = %d;";
		result = db.execSql(sql, seq);
		
		if(result) {
			db.commit();
			logger.debug("처리결과 >> " + seq + "번 게시판 카테고리 삭제 성공");
		} else {
			db.rollback();
			logger.error("처리결과 >> 데이터 삭제 실패 ");
		}
		
		logger.debug("=============== method end >> deleteBoardCategory");
		
		return result;
	}
	
	/**
	 * 게시판 카테고리 조회를 위한 기능
	 * @param seq					- 게시판 카테고리 일련번호
	 * @return BoardCategoryItem	- 게시판 카테고리 한개의 정보를 객체로 리턴
	 */
	public BoardCategoryItem viewBoardCategory(int seq) {
		logger.debug("=============== method start >> BoardCategoryItem");
		logger.debug("[PARAMS] seq=" + seq);
		
		BoardCategoryItem item = null;
		
		// 데이터 조회
		String sql = "SELECT seq, category_name, reg_date, edit_date "
				+ "FROM board_category "
				+ "WHERE seq = %d;";
		
		ResultSet rs = db.getResult(sql, seq);
		
		if(rs != null) {
			// 데이터 조회 결과 있는 경우
			try {
				rs.next();
				
				// 1) ResultSet의 모든 데이터를 변수로 추출
				int boardCategory_seq = rs.getInt(1);
				String category_name = rs.getString(2);
				String reg_date = rs.getString(3);
				String edit_date = rs.getString(4);
				
				// 2) 추출된 값을 객체로 구성
				item = new BoardCategoryItem(boardCategory_seq, category_name, reg_date, edit_date);
				
			} catch (SQLException e) {
				logger.error(e);
			} finally {
				// 3) 데이터 조회에 대한 메모리 반납
				try {
					rs.close();
				} catch (SQLException e) {}
				rs = null;
			}
		}
		
		if(item == null) {
			logger.error("데이터 조회 실패");
		} else {
			logger.debug("데이터 조회 성공");
			logger.debug(item.toString());
		}
				
		logger.debug("=============== method end >> BoardCategoryItem");
		
		return item;
	}
	
	/**
	 * 게시판 카테고리 리스트 조회를 위한 기능
	 * @return ArrayList<BoardCategoryItem>	- 게시판 카테고리 전체 리스트를 객체배열로 리턴
	 */
	public ArrayList<BoardCategoryItem> listBoardCategory() {
		logger.debug("=============== method start >> listBoardCategory");
		
		ArrayList<BoardCategoryItem> list = null;
		
		// 데이터 조회
		String sql = "SELECT seq, category_name, reg_date, edit_date "
				+ "FROM board_category;";
		
		ResultSet rs = db.getResult(sql);
		
		if(rs != null) {
			// 데이터 조회 결과 있는 경우
			try {
				list = new ArrayList<BoardCategoryItem>();
				
				while(rs.next()) {
					
					// 1) ResultSet의 모든 데이터를 변수로 추출
					int boardCategory_seq = rs.getInt(1);
					String category_name = rs.getString(2);
					String reg_date = rs.getString(3);
					String edit_date = rs.getString(4);
					
					// 2) 추출된 값을 객체로 구성
					BoardCategoryItem item = new BoardCategoryItem(boardCategory_seq, category_name, reg_date, edit_date);
					
					// 3) ArrayList에 추가
					list.add(item);
				}
			} catch (SQLException e) {
				logger.error(e);
			} finally {
				// 4) 데이터 조회에 대한 메모리 반납
				try {
					rs.close();
				} catch (SQLException e) {}
				rs = null;
			}
		}
		
		if(list == null) {
			logger.error("데이터 조회 실패");
		} else {
			logger.debug("데이터 조회 성공 >> " + list.size() + "건 조회됨");
		}
		
		logger.debug("=============== method end >> listBoardCategory");
		
		return list;
	}
	
	/**
	 * 게시판 카테고리 리스트 조회를 위한 기능
	 * @param start - 검색 범위의 시작위치
	 * @param end - 한 페이지에 보여질 글의 목록 수
	 * @return ArrayList<BoardCategoryItem> - 게시판 카테고리 전체 리스트를 객체배열로 리턴
	 */
	public ArrayList<BoardCategoryItem> listBoardCategory(int start, int end) {
		logger.debug("=============== method start >> listBoardCategory");
		logger.debug("[PARAMS] start=" + start);
		logger.debug("[PARAMS] end=" + end);
		
		ArrayList<BoardCategoryItem> list = null;
		
		// 데이터 조회
		String sql = "SELECT seq, category_name, reg_date, edit_date "
				+ "FROM board_category LIMIT %d, %d;";
		
		ResultSet rs = db.getResult(sql, start, end);
		
		if(rs != null) {
			// 데이터 조회 결과 있는 경우
			try {
				list = new ArrayList<BoardCategoryItem>();
				
				while(rs.next()) {
					
					// 1) ResultSet의 모든 데이터를 변수로 추출
					int boardCategory_seq = rs.getInt(1);
					String category_name = rs.getString(2);
					String reg_date = rs.getString(3);
					String edit_date = rs.getString(4);
					
					// 2) 추출된 값을 객체로 구성
					BoardCategoryItem item = new BoardCategoryItem(boardCategory_seq, category_name, reg_date, edit_date);
					
					// 3) ArrayList에 추가
					list.add(item);
				}
			} catch (SQLException e) {
				logger.error(e);
			} finally {
				// 4) 데이터 조회에 대한 메모리 반납
				try {
					rs.close();
				} catch (SQLException e) {}
				rs = null;
			}
		}
		
		if(list == null) {
			logger.error("데이터 조회 실패");
		} else {
			logger.debug("데이터 조회 성공 >> " + list.size() + "건 조회됨");
		}
		
		logger.debug("=============== method end >> listBoardCategory");
		
		return list;
	}
}
